package br.com.it4.zmed.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.it4.framework.persistence.exception.PersistenceException;
import br.com.it4.framework.util.exception.BusinessException;
import br.com.it4.framework.util.exception.SystemException;
import br.com.it4.zmed.entity.Paciente;
import br.com.it4.zmed.filter.PacienteFilter;
import br.com.it4.zmed.persistence.PacienteDAO;

/**
 * Classe de acesso as funcionalidades de paciente.
 * 
 * @author Mozart Silva (mozart.vsilva@gmail.com)
 * 
 */
@Service(value = "pacienteService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class PacienteServiceImpl implements PacienteService {

    /** Interface de acesso ao repositório do paciente. */
    @Autowired
    private PacienteDAO pacienteDAO;

    /** {@inheritDoc} */
    public Paciente addPaciente(Paciente paciente) throws SystemException, BusinessException {
        this.validateAddOrUpdate(paciente);

        Paciente pacienteBusca = new Paciente();
        pacienteBusca.setCodigo(paciente.getCodigo());

        // Verifica se já existe um paciente cadastro com o mesmo código.
        if (this.getPaciente(paciente.getCodigo()) != null) {
            // throw new
            // BusinessException(BusinessCode.SISTEMA_CODIGO_EXISTENTE);
        }

        try {
            return this.pacienteDAO.add(paciente);
        } catch (PersistenceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /** {@inheritDoc} */
    public Paciente updatePaciente(Paciente paciente) throws SystemException, BusinessException {
        this.validateAddOrUpdate(paciente);
        try {
            return this.pacienteDAO.update(paciente);
        } catch (PersistenceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /** {@inheritDoc} */
    public void removePaciente(Paciente paciente) throws SystemException {
        try {
            this.pacienteDAO.remove(paciente);
        } catch (PersistenceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /** {@inheritDoc} */
    public Paciente getPaciente(Long codigo) throws SystemException {
        Paciente paciente = null;
        
        try {
            paciente = this.pacienteDAO.get(codigo);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return paciente;
    }

    /** {@inheritDoc} */
    public List<Paciente> getPacientes(PacienteFilter filtro) throws SystemException {
        List<Paciente> pacientes = null;

        try {
            pacientes = this.pacienteDAO.get(filtro);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return pacientes;
    }

    /** {@inheritDoc} */
    public List<Paciente> getPacientes(PacienteFilter filtro, int registroInicio, int registroFim)
            throws SystemException {
        List<Paciente> pacientes = null;

        try {
            pacientes = this.pacienteDAO.get(filtro, registroInicio, registroFim);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return pacientes;
    }

    /** {@inheritDoc} */
    public Long getPacientesCount(PacienteFilter filtro) throws SystemException {
        Long count = null;

        try {
            count = this.pacienteDAO.getCount(filtro);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return count;
    }

    /**
     * Valida o paciente a ser salvo.
     * 
     * @param paciente
     *            O paciente a ser validado.
     * @throws BusinessException
     *             Exceção caso ocorra erro na validação.
     */
    private void validateAddOrUpdate(Paciente paciente) throws BusinessException {
        List<String> messages = new ArrayList<String>();

        // if (paciente.getCodigo() == null ||
        // paciente.getCodigo().trim().isEmpty()) {
        // messages.add(BusinessCode.SISTEMA_CODIGO_OBRIGATORIO);
        // }
        //
        // if (paciente.getCodigo() != null &&
        // paciente.getCodigo().length() > 10) {
        // messages.add(BusinessCode.SISTEMA_CODIGO_TAMANHO_INVALIDO);
        // }
        //
        // if (paciente.getNome() == null ||
        // paciente.getNome().trim().isEmpty()) {
        // messages.add(BusinessCode.SISTEMA_NOME_OBRIGATORIO);
        // }
        //
        // if (paciente.getNome() != null && paciente.getNome().length() >
        // 100) {
        // messages.add(BusinessCode.SISTEMA_NOME_TAMANHO_INVALIDO);
        // }

        if (!messages.isEmpty()) {
            throw new BusinessException(messages);
        }
    }

}